package anatex.kea.genex.extractor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ParametersDescriptor extends HashMap<Integer, int[]> {
	
	static final public int TYPE_INTEGER	= 1;
	static final public int TYPE_FLOAT		= 2;
	
	static final public int INDEX_OFFSET 	= 0;
	static final public int INDEX_LENGTH 	= 1;
	static final public int INDEX_TYPE 		= 2;
	
	static final public int NUM_PHRASES_MIN 		= 5;
	static final public int NUM_PHRASES_MAX 		= 15;
	static final public Double FACTOR_TWO_ONE_MIN 	= 1.0;
	static final public Double FACTOR_TWO_ONE_MAX 	= 3.0;
	static final public Double FACTOR_THREE_ONE_MIN = 1.0;
	static final public Double FACTOR_THREE_ONE_MAX = 5.0;
	static final public Double MIN_LENGTH_LOW_RANK_MIN = 0.3;
	static final public Double MIN_LENGTH_LOW_RANK_MAX = 3.0;
	static final public int MIN_RANK_LOW_LENGTH_MIN = 1;
	static final public int MIN_RANK_LOW_LENGTH_MAX = 20;
	static final public int FIRST_LOW_THRESH_MIN 	= 1;
	static final public int FIRST_LOW_THRESH_MAX 	= 100;
	static final public int FIRST_HIGH_THRESH_MIN 	= 1;
	static final public int FIRST_HIGH_THRESH_MAX 	= 4000;
	static final public Double FIRST_LOW_FACTOR_MIN = 1.0;
	static final public Double FIRST_LOW_FACTOR_MAX = 15.0;
	static final public Double FIRST_HIGH_FACTOR_MIN = 0.01;
	static final public Double FIRST_HIGH_FACTOR_MAX = 1.0;
	static final public int STEM_LENGTH_MIN 		= 1;
	static final public int STEM_LENGTH_MAX			= 10;
	
	protected static HashMap<Integer, Object[]> paramBounds = null;

	public ParametersDescriptor() {
		super();
		initDescriptor();
	}

	public ParametersDescriptor(int initialCapacity) {
		super(initialCapacity);
		initDescriptor();
	}

	public ParametersDescriptor(Map<Integer, int[]> m) {
		super(m);
		initDescriptor();
	}

	public ParametersDescriptor(int initialCapacity, float loadFactor) {
		super(initialCapacity, loadFactor);
		initDescriptor();
	}
	
	protected void initDescriptor() {
		paramBounds = new HashMap<Integer, Object[]>();
		
		int offset = 0;
		this.put(Parameters.NUM_PHRASES, new int[] {offset, 4, TYPE_INTEGER});
		paramBounds.put(Parameters.NUM_PHRASES, new Object[] {new Integer(NUM_PHRASES_MIN), new Integer(NUM_PHRASES_MAX)});
		offset += 4;
		this.put(Parameters.FACTOR_TWO_ONE, new int[] {offset, 9, TYPE_FLOAT});
		paramBounds.put(Parameters.FACTOR_TWO_ONE, new Object[] {new Double(FACTOR_TWO_ONE_MIN), new Double(FACTOR_TWO_ONE_MAX)});
		offset += 9;
		this.put(Parameters.FACTOR_THREE_ONE, new int[] {offset, 9, TYPE_FLOAT});
		paramBounds.put(Parameters.FACTOR_THREE_ONE, new Object[] {new Double(FACTOR_THREE_ONE_MIN), new Double(FACTOR_THREE_ONE_MAX)});
		offset += 9;
		this.put(Parameters.MIN_LENGTH_LOW_RANK, new int[] {offset, 9, TYPE_FLOAT});
		paramBounds.put(Parameters.MIN_LENGTH_LOW_RANK, new Object[] {new Double(MIN_LENGTH_LOW_RANK_MIN), new Double(MIN_LENGTH_LOW_RANK_MAX)});
		offset += 9;
		this.put(Parameters.MIN_RANK_LOW_LENGTH, new int[] {offset, 5, TYPE_INTEGER});
		paramBounds.put(Parameters.MIN_RANK_LOW_LENGTH, new Object[] {new Integer(MIN_RANK_LOW_LENGTH_MIN), new Integer(MIN_RANK_LOW_LENGTH_MAX)});
		offset += 5;
		this.put(Parameters.FIRST_LOW_THRESH, new int[] {offset, 10, TYPE_INTEGER});
		paramBounds.put(Parameters.FIRST_LOW_THRESH, new Object[] {new Integer(FIRST_LOW_THRESH_MIN), new Integer(FIRST_LOW_THRESH_MAX)});
		offset += 10;
		this.put(Parameters.FIRST_HIGH_THRESH, new int[] {offset, 12, TYPE_INTEGER});
		paramBounds.put(Parameters.FIRST_HIGH_THRESH, new Object[] {new Integer(FIRST_HIGH_THRESH_MIN), new Integer(FIRST_HIGH_THRESH_MAX)});
		offset += 12;
		this.put(Parameters.FIRST_LOW_FACTOR, new int[] {offset, 11, TYPE_FLOAT});
		paramBounds.put(Parameters.FIRST_LOW_FACTOR, new Object[] {new Double(FIRST_LOW_FACTOR_MIN), new Double(FIRST_LOW_FACTOR_MAX)});
		offset += 11;
		this.put(Parameters.FIRST_HIGH_FACTOR, new int[] {offset, 8, TYPE_FLOAT});
		paramBounds.put(Parameters.FIRST_HIGH_FACTOR, new Object[] {new Double(FIRST_HIGH_FACTOR_MIN), new Double(FIRST_HIGH_FACTOR_MAX)});
		offset += 8;
		this.put(Parameters.STEM_LENGTH, new int[] {offset, 4, TYPE_INTEGER});
		paramBounds.put(Parameters.STEM_LENGTH, new Object[] {new Integer(STEM_LENGTH_MIN), new Integer(STEM_LENGTH_MAX)});
		offset += 4;
		this.put(Parameters.SUPPRESS_PROPER, new int[] {offset, 1, TYPE_INTEGER});
		paramBounds.put(Parameters.SUPPRESS_PROPER, new Object[] {new Integer(0), new Integer(1)});
	}
	
	public static Object[] getParamBounds (Integer param) {
		return paramBounds.get(param);
	}

}
